import time
import os
import socket
import subprocess
import urllib
from urllib.error import URLError

from appium import webdriver

from utils import get_config as GC, common
import utils.get_apk_info as apk_base
import utils.get_config as config
from multiprocessing import Pool

from utils.log import err_info

attached_devices = common.get_online_devices()


def appium_start_sync():
    print('====appium_start_by_pool=====')
    ser_pool = Pool(len(attached_devices))
    ser_pool.map(start_server, attached_devices)
    ser_pool.close()
    ser_pool.join()
    time.sleep(5)


def is_runnnig(serial):
    """Determine whether server is running
    :return:True or False
    """
    response = None
    device = GC.devices.get(serial)
    url = " http://127.0.0.1:" + str(device["port"]) + "/wd/hub" + "/status"
    try:
        response = urllib.request.urlopen(url, timeout=5)
        if str(response.getcode()).startswith("2"):
            return True
        else:
            return False
    except URLError:
        return False
    finally:
        if response:
            response.close()


def check_port(host, port):
    """检查端口是否被占用"""
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((host, port))
        s.shutdown(2)
    except OSError as msg:
        print('port {} is a available.'.format(port))
        return True
    else:
        print('port {} is already use.'.format(port))
        return False


def release_port(port):
    """释放指定端口"""
    global pid
    if not common.is_mac():
        cmd_find = 'netstat -aon | findstr %s' % port
        # print(cmd_find)
        result = os.popen(cmd_find)
        text = result.read()
        if text != "":
            pid = text[-6:-1]
            # 执行被占用端口的pid
            cmd_kill = 'taskkill -f -pid %s' % pid
            # print(cmd_kill)
            os.popen(cmd_kill)
            print("apppium-server killed")
        else:
            print("The appium-server port is not occupied and is available")
        return True
    cmd = 'lsof -i:{}'.format(port)
    result = os.popen(cmd).read().strip().strip('COMMAND  PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME')
    if str(port) and 'LISTEN' in result:
        l = result.strip().split(' ')
        pid = l[4]
    if len(pid) > 0:
        cmd = 'kill {}'.format(pid)
        print('release port {}'.format(port))
        print(cmd)
        os.popen(cmd)
        return True
    else:
        return False


def start_server(devices_name):
    """
    自动启动 Appium 服务
    @return:
    """
    device = GC.devices.get(devices_name)
    serial = device.get('udid')
    bootstrap_port = device.get('bootstrap_port')
    port = int(device.get('port'))
    is_release = True
    if not check_port('0.0.0.0', port):
        is_release = release_port(port)
    time.sleep(2)
    if is_release:
        subprocess.Popen("node  main.js --port %s --bootstrap-port %s -U %s  --no-reset " % (
            port, bootstrap_port, serial), shell=True, cwd=GC.configs['appium_path'])
    time.sleep(2)


def start_android_driver(serial):
    """
        初始化安卓driver
        @return:
        """
    try:
        device = GC.devices.get(serial)
        desired_caps = {
            'platformName': 'Android',
            'platformVersion': device.get('version'),
            'deviceName': device.get('name'),
            'udid': device.get('udid'),
            'app': GC.configs['app_path_android'],
            'appPackage': apk_base.ApkInfo(config.configs["app_path_android"]).get_apk_pkg(),
            'appActivity': apk_base.ApkInfo(config.configs["app_path_android"]).get_apk_activity(),
            'noReset': True,
            'systemPort': int(device.get('system_port')),
            'newCommandTimeout': 600,
            'automationName': 'uiautomator2',
            'unicodeKeyboard': True,
            'resetKeyboard': True
        }
        dv = webdriver.Remote('http://127.0.0.1:%s/wd/hub' % str(device.get('port')), desired_caps)
        return dv
    except Exception as e:
        err_info.error(e)


if __name__ == '__main__':
    pass
